// src-tauri/src/trust_chain.rs
use ring::signature::{self, Ed25519KeyPair};
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
use std::time::{SystemTime, UNIX_EPOCH};

use crate::content_verification::ContentMetadata;

fn current_timestamp() -> u64 {
    SystemTime::now()
        .duration_since(UNIX_EPOCH)
        .expect("Time went backwards")
        .as_secs()
}

#[derive(Serialize, Deserialize, Clone)]
pub struct PeerCertificate {
    pub peer_id: String,
    pub public_key: String,
    pub role: PeerRole,
    pub issued_by: String, // 签发者peer_id
    pub issue_date: u64,
    pub expiry_date: u64,
    pub signature: String, // 签发者签名
}

#[derive(Serialize, Deserialize, Clone, PartialEq)]
pub enum PeerRole {
    God,
    Trusted,
    Regular,
}

#[derive(Serialize, Deserialize, Clone)]
pub struct ContentApproval {
    pub content_hash: String,
    pub approved_by: String, // Trusted Peer的peer_id
    pub approval_date: u64,
    pub approval_signature: String,
    pub metadata: ContentMetadata,
}

pub struct TrustChain {
    god_peer_id: String,
    god_public_key: String,
    peer_certificates: HashMap<String, PeerCertificate>,
    content_approvals: HashMap<String, ContentApproval>,
}

impl TrustChain {
    pub fn new(god_peer_id: String, god_public_key: String) -> Self {
        let mut certificates = HashMap::new();
        
        // God Peer自动获得证书
        let god_certificate = PeerCertificate {
            peer_id: god_peer_id.clone(),
            public_key: god_public_key.clone(),
            role: PeerRole::God,
            issued_by: god_peer_id.clone(),
            issue_date: SystemTime::now().duration_since(UNIX_EPOCH).expect("Time went backwards").as_secs(),
            expiry_date: SystemTime::now().duration_since(UNIX_EPOCH).expect("Time went backwards").as_secs() + 365 * 24 * 60 * 60, // 1年
            signature: "self_signed".to_string(), // 实际需要数字签名
        };
        
        certificates.insert(god_peer_id.clone(), god_certificate);
        
        Self {
            god_peer_id,
            god_public_key,
            peer_certificates: certificates,
            content_approvals: HashMap::new(),
        }
    }
    
    pub fn authorize_trusted_peer(
        &mut self, 
        applicant_peer_id: String,
        applicant_public_key: String,
        god_private_key: &[u8]
    ) -> Result<PeerCertificate, String> {
        // 验证God Peer权限
        if !self.is_god_peer(&self.god_peer_id) {
            return Err("Only God Peer can authorize trusted peers".to_string());
        }
        
        let certificate = PeerCertificate {
            peer_id: applicant_peer_id.clone(),
            public_key: applicant_public_key,
            role: PeerRole::Trusted,
            issued_by: self.god_peer_id.clone(),
            issue_date: SystemTime::now().duration_since(UNIX_EPOCH).expect("Time went backwards").as_secs(),
            expiry_date: SystemTime::now().duration_since(UNIX_EPOCH).expect("Time went backwards").as_secs() + 180 * 24 * 60 * 60, // 6个月
            signature: self.sign_certificate(&applicant_peer_id, god_private_key)?,
        };
        
        self.peer_certificates.insert(applicant_peer_id, certificate.clone());
        Ok(certificate)
    }
    
    pub fn submit_content_for_approval(
        &mut self,
        content_metadata: ContentMetadata,
        submitter_peer_id: String,
    ) -> Result<String, String> {
        // 验证提交者身份
        if !self.is_peer_authorized(&submitter_peer_id) {
            return Err("Peer not authorized".to_string());
        }
        
        let content_hash = content_metadata.compute_hash();
        
        // 将内容标记为待审核状态
        let pending_approval = ContentApproval {
            content_hash: content_hash.clone(),
            approved_by: "pending".to_string(),
            approval_date: 0,
            approval_signature: "".to_string(),
            metadata: content_metadata,
        };
        
        // 在实际系统中，这里应该将内容广播给Trusted Peers进行审核
        Ok(content_hash)
    }
    
    pub fn approve_content(
        &mut self,
        content_hash: String,
        trusted_peer_id: String,
        trusted_private_key: &[u8],
    ) -> Result<ContentApproval, String> {
        // 验证审核者权限
        if !self.is_trusted_peer(&trusted_peer_id) {
            return Err("Only trusted peers can approve content".to_string());
        }
        
        let approval = ContentApproval {
            content_hash: content_hash.clone(),
            approved_by: trusted_peer_id.clone(),
            approval_date: current_timestamp(),
            approval_signature: self.sign_approval(&content_hash, trusted_private_key)?,
            metadata: self.get_pending_content(&content_hash)?, // 获取待审核内容
        };
        
        self.content_approvals.insert(content_hash, approval.clone());
        Ok(approval)
    }
    
    pub fn is_content_approved(&self, content_hash: &str) -> bool {
        self.content_approvals.contains_key(content_hash) && 
        !self.content_approvals.get(content_hash).map(|a| a.approved_by == "pending").unwrap_or(false)
    }
    
    pub fn get_approved_content(&self) -> Vec<ContentApproval> {
        self.content_approvals.values()
            .filter(|a| a.approved_by != "pending")
            .cloned()
            .collect()
    }
    
    pub fn get_pending_content(&self, content_hash: &str) -> Result<ContentMetadata, String> {
        match self.content_approvals.get(content_hash) {
            Some(approval) if approval.approved_by == "pending" => Ok(approval.metadata.clone()),
            Some(_) => Err("Content has already been approved".to_string()),
            None => Err("No pending content found with this hash".to_string())
        }
    }
    
    pub fn is_trusted_peer(&self, peer_id: &str) -> bool {
        self.peer_certificates.get(peer_id)
            .map(|cert| cert.role == PeerRole::Trusted)
            .unwrap_or(false)
    }
    
    pub fn is_god_peer(&self, peer_id: &str) -> bool {
        self.peer_certificates.get(peer_id)
            .map(|cert| cert.role == PeerRole::God)
            .unwrap_or(false)
    }
    
    pub fn is_peer_authorized(&self, peer_id: &str) -> bool {
        self.peer_certificates.contains_key(peer_id)
    }
}